package com.zj.service.impl;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zj.entity.MediaBaseRecord;
import com.zj.mapper.MediaBaseRecordMapper;
import com.zj.model.AssignResult;
import com.zj.model.LookResult;
import com.zj.service.IMediaBaseRecordService;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import io.lindstrom.m3u8.model.MediaPlaylist;
import io.lindstrom.m3u8.model.MediaPlaylist.Builder;
import io.lindstrom.m3u8.model.MediaSegment;
import io.lindstrom.m3u8.parser.MediaPlaylistParser;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 视频录像记录 服务实现类
 * </p>
 *
 * @author jzhang
 * @since 2021-04-01
 */
@Service
@Transactional
@Slf4j
public class MediaBaseRecordServiceImpl extends ServiceImpl<MediaBaseRecordMapper, MediaBaseRecord> implements IMediaBaseRecordService {

	@Value("${weedfs.ip:localhost}")
	private String ip;
	@Value("${weedfs.port:9333}")
	private int port;
	@Value("${weedfs.ttl:1M}")
	private String ttl;
	
	private Integer duration = 10;
	
	/**
	 * 保存
	 */
	@Override
	public void record(Integer cameraId, InputStream in) {
		
		AssignResult saveToFs = saveToFs(in);
		
		MediaBaseRecord mediaBaseRecord = new MediaBaseRecord();
		mediaBaseRecord.setCameraId(cameraId);
		mediaBaseRecord.setCreateTime(LocalDateTime.now());
		mediaBaseRecord.setDuration(duration);
		mediaBaseRecord.setFid(saveToFs.getFid());
		saveOrUpdate(mediaBaseRecord);
		
	}
	
	private AssignResult saveToFs(InputStream in) {
		String string = HttpUtil.get("http://"+ip+":"+port+"/dir/assign?ttl="+ttl);
		AssignResult assignResult = JSONUtil.toBean(string, AssignResult.class);
		HttpRequest createPost = HttpUtil.createPost("http://"+assignResult.getUrl()+"/"+assignResult.getFid());
		createPost.form("file", IoUtil.readBytes(in), UUID.fastUUID().toString());
		HttpResponse execute = createPost.execute();
//		System.out.println(execute.body());
		log.debug(execute.body());
//		UploadResult uploadResult = JSONUtil.toBean(execute.body(), UploadResult.class);
		return assignResult;
	}
	
	private String getVServer(String fid) {
		String url = StrUtil.format("http://{}:{}/dir/lookup?volumeId={}", ip, port, fid);
		String string = HttpUtil.get(url);
		LookResult bean = JSONUtil.toBean(string, LookResult.class);
		return bean.getLocations().get(0).getUrl();
	}
	
	@Override
	public byte[] getHls(String cameraId, String beginTime, String endTime) {
		
		QueryWrapper<MediaBaseRecord> queryWrapper = new QueryWrapper<MediaBaseRecord>();
		queryWrapper.eq("camera_id", cameraId);
		queryWrapper.between("create_time", beginTime, endTime);
		
		List<MediaBaseRecord> list = list(queryWrapper);
		if(null == list || list.isEmpty()) {
			return new byte[1024];
		}
		
		Builder builder = MediaPlaylist.builder().version(3).targetDuration(duration).mediaSequence(new Date().getTime())
				.ongoing(false);
		
		List<MediaSegment> buildList = new ArrayList<MediaSegment>();
		for (MediaBaseRecord mediaBaseRecord : list) {
			String vServer = getVServer(mediaBaseRecord.getFid());
			String url = StrUtil.format("http://{}/{}", vServer, mediaBaseRecord.getFid());
			MediaSegment build = MediaSegment.builder().duration(mediaBaseRecord.getDuration()).uri(url).build();
			buildList.add(build);
		}
		
		MediaPlaylistParser parser = new MediaPlaylistParser();
		builder.addAllMediaSegments(buildList);
		
		String writePlaylistAsString = parser.writePlaylistAsString(builder.build());
		log.debug(writePlaylistAsString);
		return parser.writePlaylistAsBytes(builder.build());
	}

}
